package com.frontop.system.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.frontop.system.modules.sys.mapper.SysMenuMapper;
import com.frontop.system.modules.sys.model.SysMenu;
import com.frontop.system.modules.sys.service.SysMenuService;
import com.frontop.system.modules.sys.vo.MenuManageListVO;
import com.frontop.system.modules.sys.vo.MenuVO;
import com.frontop.system.modules.sys.vo.MetaVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 * @author YangJia
 * @since 2021-09-15
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    @Autowired
    private SysMenuMapper sysMenuMapper;


    @Override
    public List<MenuManageListVO> getMenuManageList(List<Integer> roleId) {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        //queryWrapper.eq("status",1);
        queryWrapper.orderByAsc("sort");
        List<SysMenu> sysMenus = list(queryWrapper);
        return recursionForMenuManageList(0, sysMenus);
    }

    @Override
    public List<MenuManageListVO> selectMenuByOrg(Integer orgId) {
        List<SysMenu> sysMenus = sysMenuMapper.selectMenuByOrg(orgId);
        return recursionForMenuManageList(0,sysMenus);
    }

    @Override
    public SysMenu getMenuInfoById(Integer id) {
        return sysMenuMapper.getMenuInfoById(id);
    }

    @Override
    public Integer isParentInChild(Map<String, Integer> map) {
        return sysMenuMapper.isParentInChild(map);
    }

    @Override
    public List<Integer> getAllChildById(Integer id) {
        return sysMenuMapper.getAllChildById(id);
    }

    @Override
    public List<MenuVO> getListMenuVO(String userName,Integer type) {
        List<SysMenu> sysMenus = sysMenuMapper.selectMenuByUserName(userName,type);
        //第一个参数必须是当前最高目录的parentId的值，这里写0也就是一级目录的parentId的值
        return recursionForMenu(0, sysMenus);
    }

    /**
     * 左侧菜单通过递归算法实现树
     *
     * @param parentId 父Id
     * @param menuList 当前所有菜单
     * @return
     */
    private List<MenuVO> recursionForMenu(int parentId, List<SysMenu> menuList) {
        List<MenuVO> list = new ArrayList<>();
        /**
         * Optional.ofNullable(menuList).orElse(new ArrayList<>())  如果menuList是空的则返回一个new ArrayList<>()
         *  .stream() 返回List中的流
         *  .filter(menu -> menu.getParentId().equals(parentId)) 筛选List，返回只有条件成立的元素（当前元素的parentId必须等于父id）
         *  .forEach 遍历这个list
         */
        Optional.ofNullable(menuList).orElse(new ArrayList<>())
                .stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .forEach(menu -> {
                    MenuVO menuVO = new MenuVO();
                    menuVO.setName(menu.getName());
                    menuVO.setId(menu.getMenuId());
                    //是否是目录
                    menuVO.setAlwaysShow(menu.getLevel().equals(1) ? true : false);
                    menuVO.setPath(menu.getPath());
                    menuVO.setComponent(StringUtils.isNotEmpty(menu.getComponent()) ? menu.getComponent() : "Layout");
                    menuVO.setMeta(new MetaVO(menu.getName(), menu.getIcon(), new ArrayList<>(Arrays.asList(1))));
                    List<MenuVO> children = recursionForMenu(menu.getMenuId(), menuList);
                    menuVO.setChildren(children);
                    list.add(menuVO);
                });
        return list;
    }

    /**
     * 菜单列表管理 递归树
     *
     * @param parentId
     * @param menuList
     * @return
     */
    private List<MenuManageListVO> recursionForMenuManageList(int parentId, List<SysMenu> menuList) {
        List<MenuManageListVO> list = new ArrayList<>();
        Optional.ofNullable(menuList).orElse(new ArrayList<>())
                .stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .forEach(menu -> {
                    MenuManageListVO menuManageListVO = new MenuManageListVO();
                    menuManageListVO.setId(menu.getMenuId());
                    menuManageListVO.setLabel(menu.getName());
                    menuManageListVO.setParentId(menu.getParentId());
                    menuManageListVO.setIcon(menu.getIcon());
                    menuManageListVO.setChildren(recursionForMenuManageList(menu.getMenuId(), menuList));
                    list.add(menuManageListVO);
                });
        return list;
    }
}
